﻿/****************************************************************************
**
* @Project : Frameworks
* @File: aggregate.h
* @Description:
* @Copyright: Copyright (c) 2014
* @Company:
* @WebSite: http://www.zchx.com/
* @author:
* @Revision History
* <pre>
* ----------------------------------------------------------------------
*   Ver     Date       Who        Comments
* ----- ----------  --------  ------------------------------------------
*   1.0  2013/08/12    yeguoxiong      FOR QT 5.1.0
* ----------------------------------------------------------------------
**
****************************************************************************/

#ifndef IPLUGIN_H
#define IPLUGIN_H

#include "extensionsystem_global.h"

#include <QObject>
#if QT_VERSION >= 0x050000
#include <QtPlugin>
#endif

namespace ExtensionSystem {

namespace Internal {
    class IPluginPrivate;
    class PluginSpecPrivate;
} // namespace Internal

class PluginManager;
class PluginSpec;

/**
 * @class IPlugin
 * @brief 插件接口基类
 * @details 所有插件必须实现的抽象接口类，定义了插件的生命周期和基本功能
 *          插件管理器通过此接口与插件交互
 *          // TODO: Qt5.15.2升级 - 考虑使用Q_DECLARE_INTERFACE宏的现代写法
 */
class EXTENSIONSYSTEM_EXPORT IPlugin : public QObject
{
    Q_OBJECT
    // Q_INTERFACES宏已在文件末尾定义

public:
    /**
     * @enum ShutdownFlag
     * @brief 关闭标志枚举
     * @details 指示插件在关闭时是同步还是异步完成
     */
    enum ShutdownFlag {
        SynchronousShutdown,    ///< 同步关闭，插件立即完成关闭
        AsynchronousShutdown   ///< 异步关闭，插件将在稍后完成关闭并发出信号
    };

    /**
     * @brief 构造函数
     * @details 初始化插件基类
     */
    IPlugin();

    /**
     * @brief 析构函数
     * @details 清理插件资源
     */
    virtual ~IPlugin();

    /**
     * @brief 初始化插件
     * @param arguments 插件启动参数
     * @param errorString 错误信息输出
     * @return 初始化成功返回true，否则返回false
     * @details 插件的主要初始化入口点，在插件加载后调用
     *          必须由派生类实现
     */
    virtual bool initialize(const QStringList &arguments, QString *errorString) = 0;

    /**
     * @brief 扩展初始化完成
     * @details 当所有插件的initialize方法都已调用后调用
     *          用于插件之间的交互和依赖设置
     *          必须由派生类实现
     */
    virtual void extensionsInitialized() = 0;

    /**
     * @brief 延迟初始化
     * @return 初始化成功返回true，否则返回false
     * @details 用于非关键的初始化工作，可以在主应用程序启动后延迟执行
     *          默认为空实现
     */
    virtual bool delayedInitialize() { return false; }

    /**
     * @brief 即将关闭
     * @return 关闭标志，指示同步或异步关闭
     * @details 在应用程序即将关闭时调用，用于插件清理资源
     *          默认为同步关闭
     */
    virtual ShutdownFlag aboutToShutdown() { return SynchronousShutdown; }

    /**
     * @brief 获取插件规范
     * @return 插件规范对象指针
     * @details 包含插件的元数据和状态信息
     */
    PluginSpec *pluginSpec() const;

    /**
     * @brief 添加对象到全局对象池
     * @param obj 要添加的对象指针
     * @details 注册对象，使其可被其他插件访问
     *          // TODO: Qt5.15.2升级 - 添加空指针检查
     */
    void addObject(QObject *obj);

    /**
     * @brief 添加自动释放对象到全局对象池
     * @param obj 要添加的对象指针
     * @details 注册对象，在插件卸载时自动释放
     *          // TODO: Qt5.15.2升级 - 添加空指针检查
     */
    void addAutoReleasedObject(QObject *obj);

    /**
     * @brief 从全局对象池移除对象
     * @param obj 要移除的对象指针
     * @details 取消对象注册
     *          // TODO: Qt5.15.2升级 - 添加空指针检查
     */
    void removeObject(QObject *obj);

Q_SIGNALS:
    /**
     * @brief 异步关闭完成信号
     * @details 当插件以异步方式关闭完成时发出
     */
    void asynchronousShutdownFinished();

private:
    Internal::IPluginPrivate *d; ///< 私有实现指针

    friend class Internal::PluginSpecPrivate;
};

} // namespace ExtensionSystem

// The macros Q_EXPORT_PLUGIN, Q_EXPORT_PLUGIN2 become obsolete in Qt 5.
#if QT_VERSION >= 0x050000
#    if defined(Q_EXPORT_PLUGIN)
#        undef Q_EXPORT_PLUGIN
#        undef Q_EXPORT_PLUGIN2
#    endif
#    define Q_EXPORT_PLUGIN(plugin)
#    define Q_EXPORT_PLUGIN2(function, plugin)
#else
#    define Q_PLUGIN_METADATA(x)
#endif

#define PLUGIN_IID "org.BlueBlazer.Frameworks.Plugin"
Q_DECLARE_INTERFACE(ExtensionSystem::IPlugin, PLUGIN_IID)

#endif // IPLUGIN_H
